from typing import Dict, List, Optional
from sqlalchemy import or_
from ..models.role import Role
from ..models.user_role import UserRole
from ..models.role_permission import RolePermission
from ..extensions.extensions import db
from datetime import datetime, timezone
from flask import current_app

class RoleService:
    @staticmethod
    def get_role_list(page: int = 1, per_page: int = 10, keyword: Optional[str] = None) -> Dict:
        """
        获取角色列表
        :param page: 页码
        :param per_page: 每页数量
        :param keyword: 搜索关键词
        :return: 角色列表和分页信息
        """
        query = Role.query.filter_by(deleted=False)
        
        # 关键词搜索
        if keyword:
            query = query.filter(
                or_(
                    Role.role_name.like(f'%{keyword}%'),
                    Role.role_code.like(f'%{keyword}%'),
                    Role.description.like(f'%{keyword}%')
                )
            )
        
        # 分页
        pagination = query.order_by(Role.sort_order.asc(), Role.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        return {
            'total': pagination.total,
            'page': page,
            'per_page': per_page,
            'items': [item.to_dict() for item in pagination.items]
        }

    @staticmethod
    def get_role_by_id(role_id: int) -> Optional[Role]:
        """
        根据ID获取角色
        :param role_id: 角色ID
        :return: 角��对象
        """
        return Role.query.filter_by(id=role_id, deleted=False).first()

    @staticmethod
    def get_role_by_code(role_code: str) -> Optional[Role]:
        """
        根据角色代码获取角色
        :param role_code: 角色代码
        :return: 角色对象
        """
        return Role.query.filter_by(role_code=role_code, deleted=False).first()

    @staticmethod
    def create_role(role_data: Dict) -> Role:
        """
        创建角色
        :param role_data: 角色数据
        :return: 角色对象
        """
        role = Role(
            role_name=role_data['role_name'],
            role_code=role_data['role_code'],
            description=role_data.get('description'),
            sort_order=role_data.get('sort_order', 0),
            status=role_data.get('status', True)
        )
        
        db.session.add(role)
        db.session.commit()
        return role

    @staticmethod
    def update_role(role: Role, role_data: Dict) -> Role:
        """
        更新角色信息
        :param role: 角色对象
        :param role_data: 更新的角色数据
        :return: 更新后的角色对象
        """
        for key, value in role_data.items():
            if hasattr(role, key):
                setattr(role, key, value)
        
        role.updated_at = datetime.now(timezone.utc)
        db.session.commit()
        return role

    @staticmethod
    def delete_role(role: Role) -> bool:
        """
        删除角色（软删除）
        :param role: 角色对象
        :return: 是否成功
        """
        role.deleted = True
        role.updated_at = datetime.now(timezone.utc)
        db.session.commit()
        return True

    @staticmethod
    def update_role_status(role: Role, status: bool) -> Role:
        """
        更新角色状态
        :param role: 角色对象
        :param status: 状态
        :return: 更新后的角色对象
        """
        role.status = status
        role.updated_at = datetime.now(timezone.utc)
        db.session.commit()
        return role

    @staticmethod
    def get_role_permissions(role_id: int) -> List[int]:
        """
        获取角色的权限ID列表
        :param role_id: 角色ID
        :return: 权限ID列表
        """
        permissions = RolePermission.query.filter_by(
            role_id=role_id, deleted=False
        ).all()
        return [p.permission_id for p in permissions]

    @staticmethod
    def get_user_roles(user_id: int) -> List[int]:
        """
        获取用户的角色ID列表
        :param user_id: 用户ID
        :return: 角色ID列表
        """
        roles = UserRole.query.filter_by(
            user_id=user_id, deleted=False
        ).all()
        return [r.role_id for r in roles]

    @staticmethod
    def get_role_permissions(role_id):
        """获取角色的所有权限"""
        try:
            from ..models.role_permission import RolePermission
            from ..models.permission import Permission
            
            permissions = (Permission.query
                          .join(RolePermission, RolePermission.permission_id == Permission.id)
                          .filter(RolePermission.role_id == role_id)
                          .filter(Permission.status == 1)  # 只获取启用的权限
                          .all())
            return permissions
        except Exception as e:
            current_app.logger.error(f"获取角色权限失败: {str(e)}")
            return [] 